#ifndef HASH_H
#define HASH_H

// Si no se incluyen, el compilador protesta
#include <stdbool.h>
#include <stdlib.h>


typedef struct hash hash_t;

typedef struct hash_iter hash_iter_t;

typedef void (*hash_destruir_dato_t)(void *);


//post: crea una tabla hash vacía.
hash_t *hash_crear(hash_destruir_dato_t destruir_dato);

//pre: tabla hash y clave existen.
//post: devuelve true si el dato si la operación fue exitosa.
bool hash_guardar(hash_t *hash, const char *clave, void *dato);

//pre: tabla hash creada y clave valida.
//post: devuelve el dato asociado a la clave y que fue eliminado de la tabla hash. Devuelve NULL si la operacion no se llevo a cabo.
void *hash_borrar(hash_t *hash, const char *clave);

//pre: tabla hash creada y clave valida.
//post: devuelve el dato asociado a la clave. Devuelve NULL si la operacion no se llevo a cabo.
void *hash_obtener(const hash_t *hash, const char *clave);

//pre: tabla hash creada y clave valida.
//post: true si la clave esta asociada a algun dato de la tabla.
bool hash_pertenece(const hash_t *hash, const char *clave);

//pre: la tabla hash fue creada.
//post: devuelve la cantidad de datos almacenados en la tabla.
size_t hash_cantidad(const hash_t *hash);

//pre: tabla hash creada.
//post: destruye la tabla y los datos almacenados en el.
void hash_destruir(hash_t *hash);

//pre: la tabla hash fue creada.
//post: crea un iterador que apunta al primer dato almacenado en la tabla,
//si el iterador es creado en una tabla vacia, este se vuelve inservible.
hash_iter_t *hash_iter_crear(const hash_t *hash);

//el iterador apunta al siquiente elemente en la tabla hash. si el iterador
//llega al final de la tabla, el mismo se vuelve inservible. 
//pre: el iterador fue creado.
//post: true si la operacion fue exitosa.
bool hash_iter_avanzar(hash_iter_t *iter);

//pre: el iterador fue creado.
//post: devuelve la clave del dato al cual apunta el iterador. NULL si 
//la tabla esta vacia o el iterador se encuentra el final de la tabla.
const char *hash_iter_ver_actual(const hash_iter_t *iter);

//pre: el iterador fue creado.
//post: devuelve true si el iterador se encuentra la final de la tabla hash o si la tabla esta vacia.
bool hash_iter_al_final(const hash_iter_t *iter);

//pre: el iterador fue creado.
//post: destruye el iterador.
void hash_iter_destruir(hash_iter_t* iter);

#endif
